package com.jlwl.houseservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jlwl.houseservice.entity.Employee;
import com.jlwl.houseservice.entity.EmployeeSchedule;
import com.jlwl.houseservice.mapper.EmployeeScheduleMapper;
import com.jlwl.houseservice.service.EmployeeScheduleService;
import com.jlwl.houseservice.service.EmployeeService;
import com.jlwl.houseservice.vo.BatchScheduleVO;
import com.jlwl.houseservice.vo.ScheduleQueryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 员工排班Service实现类
 */
@Service
public class EmployeeScheduleServiceImpl extends ServiceImpl<EmployeeScheduleMapper, EmployeeSchedule> implements EmployeeScheduleService {

    @Autowired
    private EmployeeService employeeService;

    @Override
    public Page<EmployeeSchedule> pageList(ScheduleQueryVO queryVO) {
        LambdaQueryWrapper<EmployeeSchedule> queryWrapper = new LambdaQueryWrapper<>();
        
        // 员工ID筛选
        if (queryVO.getEmployeeId() != null) {
            queryWrapper.eq(EmployeeSchedule::getEmployeeId, queryVO.getEmployeeId());
        }
        
        // 日期范围筛选
        if (queryVO.getStartDate() != null) {
            queryWrapper.ge(EmployeeSchedule::getScheduleDate, queryVO.getStartDate());
        }
        
        if (queryVO.getEndDate() != null) {
            queryWrapper.le(EmployeeSchedule::getScheduleDate, queryVO.getEndDate());
        }
        
        // 状态筛选
        if (queryVO.getStatus() != null) {
            queryWrapper.eq(EmployeeSchedule::getStatus, queryVO.getStatus());
        }
        
        // 订单编号筛选
        if (StringUtils.hasText(queryVO.getOrderNo())) {
            queryWrapper.eq(EmployeeSchedule::getOrderNo, queryVO.getOrderNo());
        }
        
        // 默认按日期升序排序
        queryWrapper.orderByAsc(EmployeeSchedule::getScheduleDate);
        
        // 分页查询
        return page(new Page<>(queryVO.getPage(), queryVO.getSize()), queryWrapper);
    }

    @Override
    public List<EmployeeSchedule> getEmployeeSchedules(Integer employeeId, LocalDate startDate, LocalDate endDate) {
        return list(new LambdaQueryWrapper<EmployeeSchedule>()
                .eq(EmployeeSchedule::getEmployeeId, employeeId)
                .ge(EmployeeSchedule::getScheduleDate, startDate)
                .le(EmployeeSchedule::getScheduleDate, endDate)
                .orderByAsc(EmployeeSchedule::getScheduleDate));
    }

    @Override
    @Transactional
    public boolean createSchedule(EmployeeSchedule schedule) {
        schedule.setCreatedAt(LocalDateTime.now());
        schedule.setUpdatedAt(LocalDateTime.now());
        
        return save(schedule);
    }

    @Override
    @Transactional
    public boolean updateSchedule(EmployeeSchedule schedule) {
        EmployeeSchedule existSchedule = getById(schedule.getId());
        if (existSchedule == null) {
            return false;
        }
        
        schedule.setUpdatedAt(LocalDateTime.now());
        
        return updateById(schedule);
    }

    @Override
    @Transactional
    public boolean deleteSchedule(Integer id) {
        return removeById(id);
    }

    @Override
    @Transactional
    public boolean batchSetSchedule(BatchScheduleVO batchScheduleVO) {
        // 检查日期范围
        LocalDate startDate = batchScheduleVO.getStartDate();
        LocalDate endDate = batchScheduleVO.getEndDate();
        
        if (startDate.isAfter(endDate)) {
            return false;
        }
        
        // 获取日期范围内的所有日期
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dateList.add(currentDate);
            currentDate = currentDate.plusDays(1);
        }
        
        // 拼接时间段
        String timeSlots = String.join(",", batchScheduleVO.getTimeSlots());
        
        // 批量创建排班
        List<EmployeeSchedule> scheduleList = new ArrayList<>();
        
        for (Integer employeeId : batchScheduleVO.getEmployeeIds()) {
            for (LocalDate date : dateList) {
                // 检查是否已存在排班
                LambdaQueryWrapper<EmployeeSchedule> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(EmployeeSchedule::getEmployeeId, employeeId)
                        .eq(EmployeeSchedule::getScheduleDate, date);
                
                if (count(queryWrapper) > 0) {
                    // 已存在排班，更新
                    update(new LambdaUpdateWrapper<EmployeeSchedule>()
                            .eq(EmployeeSchedule::getEmployeeId, employeeId)
                            .eq(EmployeeSchedule::getScheduleDate, date)
                            .set(EmployeeSchedule::getTimeSlots, timeSlots)
                            .set(EmployeeSchedule::getStatus, batchScheduleVO.getStatus())
                            .set(StringUtils.hasText(batchScheduleVO.getRemark()), EmployeeSchedule::getRemark, batchScheduleVO.getRemark())
                            .set(EmployeeSchedule::getUpdatedAt, LocalDateTime.now()));
                } else {
                    // 不存在排班，创建
                    EmployeeSchedule schedule = new EmployeeSchedule();
                    schedule.setEmployeeId(employeeId);
                    schedule.setScheduleDate(date);
                    schedule.setTimeSlots(timeSlots);
                    schedule.setStatus(batchScheduleVO.getStatus());
                    schedule.setRemark(batchScheduleVO.getRemark());
                    schedule.setCreatedAt(LocalDateTime.now());
                    schedule.setUpdatedAt(LocalDateTime.now());
                    
                    scheduleList.add(schedule);
                }
            }
        }
        
        // 批量保存
        if (!scheduleList.isEmpty()) {
            saveBatch(scheduleList);
        }
        
        return true;
    }

    @Override
    @Transactional
    public boolean updateScheduleStatus(Integer id, Integer status) {
        return update(new LambdaUpdateWrapper<EmployeeSchedule>()
                .eq(EmployeeSchedule::getId, id)
                .set(EmployeeSchedule::getStatus, status)
                .set(EmployeeSchedule::getUpdatedAt, LocalDateTime.now()));
    }

    @Override
    @Transactional
    public boolean assignOrderToSchedule(Integer id, String orderNo) {
        return update(new LambdaUpdateWrapper<EmployeeSchedule>()
                .eq(EmployeeSchedule::getId, id)
                .set(EmployeeSchedule::getOrderNo, orderNo)
                .set(EmployeeSchedule::getStatus, 2) // 已预约
                .set(EmployeeSchedule::getUpdatedAt, LocalDateTime.now()));
    }

    @Override
    @Transactional
    public boolean cancelOrderAssignment(Integer id) {
        return update(new LambdaUpdateWrapper<EmployeeSchedule>()
                .eq(EmployeeSchedule::getId, id)
                .set(EmployeeSchedule::getOrderNo, null)
                .set(EmployeeSchedule::getStatus, 1) // 可用
                .set(EmployeeSchedule::getUpdatedAt, LocalDateTime.now()));
    }

    @Override
    public List<Map<String, Object>> getAvailableEmployees(String jobType, LocalDate date, String timeSlot) {
        // 获取指定工作类型的员工
        List<Employee> employees = employeeService.getEmployeesByJobType(jobType);
        
        // 获取可用员工
        List<Map<String, Object>> availableEmployees = new ArrayList<>();
        
        for (Employee employee : employees) {
            // 查询员工在指定日期的排班
            List<EmployeeSchedule> schedules = list(new LambdaQueryWrapper<EmployeeSchedule>()
                    .eq(EmployeeSchedule::getEmployeeId, employee.getId())
                    .eq(EmployeeSchedule::getScheduleDate, date));
            
            boolean isAvailable = true;
            
            if (!schedules.isEmpty()) {
                for (EmployeeSchedule schedule : schedules) {
                    // 检查时间段是否冲突
                    if (schedule.getStatus() == 2 && schedule.getTimeSlots().contains(timeSlot)) {
                        isAvailable = false;
                        break;
                    }
                }
            }
            
            if (isAvailable) {
                Map<String, Object> employeeMap = new HashMap<>();
                employeeMap.put("id", employee.getId());
                employeeMap.put("name", employee.getName());
                employeeMap.put("phone", employee.getPhone());
                employeeMap.put("avatar", employee.getAvatar());
                employeeMap.put("jobType", employee.getJobType());
                employeeMap.put("workYears", employee.getWorkYears());
                employeeMap.put("rating", employee.getRating());
                employeeMap.put("serviceCount", employee.getServiceCount());
                
                availableEmployees.add(employeeMap);
            }
        }
        
        return availableEmployees;
    }
} 